import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;

/**
 * @author Egor Kulikov (egor@egork.net)
 */
public class Highways {
	@SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
	private InputReader in;
	private PrintWriter out;

	private void solve() {
		int cityCount = in.readInt();
		WeightedGraph graph = new BidirectionalWeightedGraph(new SparseWeightedGraph(cityCount));
		int roadCount = in.readInt();
		int start = in.readInt() - 1;
		int finish = in.readInt() - 1;
		for (int i = 0; i < roadCount; i++) {
			int source = in.readInt() - 1;
			int destination = in.readInt() - 1;
			int weight = in.readInt();
			graph.addWeightedEdge(source, destination, weight);
		}
		int result = getDistance(graph, start, finish);
		if (result == Integer.MAX_VALUE)
			out.println("NONE");
		else
			out.println(result);
	}

	public enum GraphType {
		DENSE, SPARSE
	}

	public interface Edge {
		public int getSource();
		public int getDestination();
		public int getWeight();
		public int getFlow();
		public int getCurrentFlow();
		public void addFlow(int flow);
	}

	public static class SimpleEdge implements Edge {
		private final int source;
		private final int destination;

		public SimpleEdge(int source, int destination) {
			this.source = source;
			this.destination = destination;
		}

		public int getSource() {
			return source;
		}

		public int getDestination() {
			return destination;
		}

		public int getWeight() {
			return 1;
		}

		public int getFlow() {
			return 0;
		}

		public int getCurrentFlow() {
			return 0;
		}

		public void addFlow(int flow) {
			if (flow == 0)
				return;
			throw new IllegalArgumentException("Not enough flow");
		}
	}

	public static class WeightedEdge extends SimpleEdge {
		private final int weight;

		public WeightedEdge(int source, int destination, int weight) {
			super(source, destination);
			this.weight = weight;
		}

		@Override
		public int getWeight() {
			return weight;
		}
	}

	public static class FlowEdge extends WeightedEdge {
		private int flow;
		private int currentFlow = 0;

		public FlowEdge(int source, int destination, int weight, int flow) {
			super(source, destination, weight);
			this.flow = flow;
		}

		@Override
		public int getFlow() {
			return flow;
		}

		@Override
		public int getCurrentFlow() {
			return currentFlow;
		}

		@Override
		public void addFlow(int flow) {
			if (this.flow < flow)
				throw new IllegalArgumentException("Not enough flow");
			currentFlow += flow;
			this.flow -= flow;
		}
	}

	public static class ReverseEdge extends FlowEdge {
		private final FlowEdge edge;

		public ReverseEdge(FlowEdge edge) {
			super(edge.getDestination(), edge.getSource(), -edge.getWeight(), 0);
			this.edge = edge;
		}

		@Override
		public int getFlow() {
			return edge.getCurrentFlow();
		}

		@Override
		public int getCurrentFlow() {
			return 0;
		}

		@Override
		public void addFlow(int flow) {
			edge.addFlow(-flow);
		}
	}

	public interface Graph {
		public int getVertexCount();
		public void addEdge(int source, int destination);
		public Iterable<Edge> getIncident(int source);
		public GraphType getType();
	}

	public interface WeightedGraph extends Graph {
		public void addWeightedEdge(int source, int destination, int weight);
	}

	public interface FlowGraph extends Graph {
		public void addEdge(int source, int destination, int flow);
	}

	public interface FlowWeightedGraph extends WeightedGraph, FlowGraph {
		public void addWeightedEdge(int source, int destination, int weight, int flow);
	}

	public static class BidirectionalGraph implements Graph {
		private final Graph delegate;

		public BidirectionalGraph(Graph delegate) {
			this.delegate = delegate;
		}

		public int getVertexCount() {
			return delegate.getVertexCount();
		}

		public void addEdge(int source, int destination) {
			delegate.addEdge(source, destination);
			delegate.addEdge(destination, source);
		}

		public Iterable<Edge> getIncident(int source) {
			return delegate.getIncident(source);
		}

		public GraphType getType() {
			return delegate.getType();
		}
	}

	public static class BidirectionalWeightedGraph extends BidirectionalGraph implements WeightedGraph {
		private final WeightedGraph delegate;

		public BidirectionalWeightedGraph(WeightedGraph delegate) {
			super(delegate);
			this.delegate = delegate;
		}

		public void addWeightedEdge(int source, int destination, int weight) {
			delegate.addWeightedEdge(source, destination, weight);
			delegate.addWeightedEdge(destination, source, weight);
		}
	}

	public static class SparseGraph implements Graph {
		private final int vertexCount;
		protected final List<Edge>[] edges;

		public SparseGraph(int vertexCount) {
			this.vertexCount = vertexCount;
			//noinspection unchecked
			edges = new List[vertexCount];
			for (int i = 0; i < vertexCount; i++)
				edges[i] = new ArrayList<Edge>();
		}

		public int getVertexCount() {
			return vertexCount;
		}

		public void addEdge(int source, int destination) {
			edges[source].add(new SimpleEdge(source, destination));
		}

		public Iterable<Edge> getIncident(int source) {
			return edges[source];
		}

		public GraphType getType() {
			return GraphType.SPARSE;
		}
	}

	public static class SparseWeightedGraph extends SparseGraph implements WeightedGraph {
		public SparseWeightedGraph(int vertexCount) {
			super(vertexCount);
		}

		public void addWeightedEdge(int source, int destination, int weight) {
			edges[source].add(new WeightedEdge(source, destination, weight));
		}
	}

	public static class SparseFlowGraph extends SparseWeightedGraph implements FlowWeightedGraph {
		public SparseFlowGraph(int vertexCount) {
			super(vertexCount);
		}

		public void addWeightedEdge(int source, int destination, int weight, int flow) {
			FlowEdge direct = new FlowEdge(source, destination, weight, flow);
			edges[source].add(direct);
			edges[destination].add(new ReverseEdge(direct));
		}

		public void addEdge(int source, int destination, int flow) {
			addWeightedEdge(source, destination, flow, 1);
		}
	}

	public interface DenseGraph extends Graph {
		public boolean hasEdge(int source, int destination);
		public int getWeight(int source, int destination);
		public int getFlow(int source, int destination);
		public int getCurrentFlow(int source, int destination);
		public void addFlow(int source, int destination, int flow);
	}

	public static class DenseEdge implements Edge, Iterator<Edge> {
		private final int source;
		private final DenseGraph graph;
		private int destination = -1;
		private int nextDestination;

		public DenseEdge(int source, DenseGraph graph) {
			this.source = source;
			this.graph = graph;
			advance();
		}

		private void advance() {
			int vertexCount = graph.getVertexCount();
			for (nextDestination = destination + 1; nextDestination < vertexCount && graph.hasEdge(source,
					nextDestination); nextDestination++);
		}

		public int getSource() {
			return source;
		}

		public int getDestination() {
			return destination;
		}

		public int getWeight() {
			return graph.getWeight(source, destination);
		}

		public int getFlow() {
			return graph.getFlow(source, destination);
		}

		public int getCurrentFlow() {
			return graph.getCurrentFlow(source, destination);
		}

		public void addFlow(int flow) {
			graph.addFlow(source, destination, flow);
		}

		public boolean hasNext() {
			return nextDestination != graph.getVertexCount();
		}

		public Edge next() {
			destination = nextDestination;
			advance();
			return this;
		}

		public void remove() {
			throw new UnsupportedOperationException();
		}
	}

	public static abstract class AbstractDenseGraph implements DenseGraph {
		protected final int vertexCount;

		protected AbstractDenseGraph(int vertexCount) {
			this.vertexCount = vertexCount;
		}

		public int getVertexCount() {
			return vertexCount;
		}

		public Iterable<Edge> getIncident(final int source) {
			return new Iterable<Edge>() {
				public Iterator<Edge> iterator() {
					return new DenseEdge(source, AbstractDenseGraph.this);
				}
			};
		}

		public boolean hasEdge(int source, int destination) {
			return false;
		}

		public int getWeight(int source, int destination) {
			return 1;
		}

		public int getFlow(int source, int destination) {
			return 0;
		}

		public int getCurrentFlow(int source, int destination) {
			return 0;
		}

		public void addFlow(int source, int destination, int flow) {
			throw new UnsupportedOperationException();
		}

		public GraphType getType() {
			return GraphType.DENSE;
		}
	}

	public static class BooleanDenseGraph extends AbstractDenseGraph {
		private final boolean[][] edges;

		public BooleanDenseGraph(int vertexCount) {
			super(vertexCount);
			edges = new boolean[vertexCount][vertexCount];
		}

		public void addEdge(int source, int destination) {
			edges[source][destination] = true;
		}

		public boolean hasEdge(int source, int destination) {
			return edges[source][destination];
		}
	}

	public static class WeightedDenseGraph extends AbstractDenseGraph implements WeightedGraph {
		private final int[][] edges;

		public WeightedDenseGraph(int vertexCount) {
			super(vertexCount);
			edges = new int[vertexCount][vertexCount];
			for (int i = 0; i < vertexCount; i++) {
				Arrays.fill(edges[i], Integer.MAX_VALUE);
				edges[i][i] = 0;
			}
		}


		public boolean hasEdge(int source, int destination) {
			return edges[source][destination] != Integer.MAX_VALUE;
		}

		public int getWeight(int source, int destination) {
			return edges[source][destination];
		}

		public void addWeightedEdge(int source, int destination, int weight) {
			edges[source][destination] = Math.min(edges[source][destination], weight);
		}

		public void addEdge(int source, int destination) {
			addWeightedEdge(source, destination, 1);
		}
	}

	public static class FlowDenseGraph extends AbstractDenseGraph implements FlowGraph {
		private int[][] flow;
		private int[][] currentFlow;

		protected FlowDenseGraph(int vertexCount) {
			super(vertexCount);
			flow = new int[vertexCount][vertexCount];
			currentFlow = new int[vertexCount][vertexCount];
		}

		public void addEdge(int source, int destination, int flow) {
			this.flow[source][destination] += flow;
		}

		@Override
		public boolean hasEdge(int source, int destination) {
			return currentFlow[source][destination] != 0 || flow[source][destination] != 0;
		}

		@Override
		public int getFlow(int source, int destination) {
			return flow[source][destination] + currentFlow[destination][source];
		}

		@Override
		public int getCurrentFlow(int source, int destination) {
			return currentFlow[source][destination];
		}

		@Override
		public void addFlow(int source, int destination, int flow) {
			if (flow > getFlow(source, destination))
				throw new IllegalArgumentException("Not enough flow");
			int backFlow = Math.min(currentFlow[destination][source], flow);
			currentFlow[destination][source] -= backFlow;
			flow -= backFlow;
			this.flow[source][destination] -= flow;
			currentFlow[source][destination] += flow;
		}

		public void addEdge(int source, int destination) {}
	}

	public static class FlowWeightedDenseGraph extends FlowDenseGraph implements FlowWeightedGraph {
		private int[][] weights;

		protected FlowWeightedDenseGraph(int vertexCount) {
			super(vertexCount);
			weights = new int[vertexCount][vertexCount];
		}

		public void addWeightedEdge(int source, int destination, int weight, int flow) {
			super.addEdge(source, destination, flow);
			weights[source][destination] = weight;
		}

		public void addWeightedEdge(int source, int destination, int weight) {
			weights[source][destination] = weight;
		}

		@Override
		public int getWeight(int source, int destination) {
			return weights[source][destination];
		}
	}

	public static int[] getDistances(Graph graph, int source) {
		if (graph instanceof WeightedGraph) {
			if (graph.getType() == GraphType.DENSE)
				return findDenseDistances(graph, source);
			return findSparseDistances(graph, source);
		}
		return findUnweightedDistances(graph, source);
	}

	private static int[] findSparseDistances(Graph graph, int source) {
		int vertexCount = graph.getVertexCount();
		final int[] distance = new int[vertexCount];
		Arrays.fill(distance, Integer.MAX_VALUE);
		distance[source] = 0;
		PriorityQueue<Integer> queue = new PriorityQueue<Integer>(vertexCount, new Comparator<Integer>() {
			public int compare(Integer o1, Integer o2) {
				return distance[o1] - distance[o2];
			}
		});
		queue.add(source);
		while (!queue.isEmpty()) {
			int current = queue.poll();
			for (Edge edge : graph.getIncident(current)) {
				int next = edge.getDestination();
				int weight = edge.getWeight();
				if (distance[next] > distance[current] + weight) {
					distance[next] = distance[current] + weight;
					queue.add(next);
				}
			}
		}
		return distance;
	}

	private static int[] findDenseDistances(Graph graph, int source) {
		int vertexCount = graph.getVertexCount();
		int[] distance = new int[vertexCount];
		Arrays.fill(distance, Integer.MAX_VALUE);
		distance[source] = 0;
		boolean[] visited = new boolean[vertexCount];
		for (int i = 0; i < vertexCount; i++) {
			int shortest = Integer.MAX_VALUE;
			int index = -1;
			for (int j = 0; j < vertexCount; j++) {
				if (!visited[j] && distance[j] < shortest) {
					shortest = distance[j];
					index = j;
				}
			}
			if (index == -1)
				break;
			visited[index] = true;
			for (Edge edge : graph.getIncident(index)) {
				int destination = edge.getDestination();
				int weight = edge.getWeight();
				if (distance[destination] > distance[index] + weight)
					distance[destination] = distance[index] + weight;
			}
		}
		return distance;
	}

	private static int[] findUnweightedDistances(Graph graph, int source) {
		int vertexCount = graph.getVertexCount();
		int[] distance = new int[vertexCount];
		Arrays.fill(distance, Integer.MAX_VALUE);
		distance[source] = 0;
		Queue<Integer> queue = new ArrayDeque<Integer>(vertexCount);
		queue.add(source);
		while (!queue.isEmpty()) {
			int current = queue.poll();
			for (Edge edge : graph.getIncident(current)) {
				int next = edge.getDestination();
				if (distance[next] != Integer.MAX_VALUE) {
					distance[next] = distance[current] + 1;
					queue.add(next);
				}
			}
		}
		return distance;
	}

	public static int getDistance(Graph graph, int source, int destination) {
		return getDistances(graph, source)[destination];
	}

	public static void main(String[] args) {
		new Highways().run();
	}

	private Highways() {
		@SuppressWarnings({"UnusedDeclaration"})
		String id = getClass().getName().toLowerCase();
		//noinspection EmptyTryBlock
		try {
//			System.setIn(new FileInputStream(id + ".in"));
//			System.setOut(new PrintStream(new FileOutputStream(id + ".out")));
//			System.setIn(new FileInputStream("input.txt"));
//			System.setOut(new PrintStream(new FileOutputStream("output.txt")));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		in = new InputReader(System.in);
		out = new PrintWriter(System.out);
	}

	private void run() {
		//noinspection InfiniteLoopStatement
		int testCount = in.readInt();
		for (int i = 0; i < testCount; i++)
//		while (true)
			solve();
		exit();
	}

	@SuppressWarnings({"UnusedDeclaration"})
	private void exit() {
		out.close();
		System.exit(0);
	}

	@SuppressWarnings({"UnusedDeclaration"})
	public static class InputReader {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar, numChars;

		public InputReader(InputStream stream) {
			this.stream = stream;
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public int readInt() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long readLong() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public String readString() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuffer res = new StringBuffer();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		private boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private String readLine0() {
			StringBuffer buf = new StringBuffer();
			int c = read();
			while (c != '\n' && c != -1) {
				if (c != '\r')
					buf.appendCodePoint(c);
				c = read();
			}
			return buf.toString();
		}

		public String readLine() {
			String s = readLine0();
			while (s.trim().length() == 0)
				s = readLine0();
			return s;
		}

		public String readLine(boolean ignoreEmptyLines) {
			if (ignoreEmptyLines)
				return readLine();
			else
				return readLine0();
		}

		public BigInteger readBigInteger() {
			try {
				return new BigInteger(readString());
			} catch (NumberFormatException e) {
				throw new InputMismatchException();
			}
		}

		public char readCharacter() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			return (char) c;
		}

		public double readDouble() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			double res = 0;
			while (!isSpaceChar(c) && c != '.') {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, readInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			if (c == '.') {
				c = read();
				double m = 1;
				while (!isSpaceChar(c)) {
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, readInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}
			return res * sgn;
		}

		public int[] readIntArray(int size) {
			int[] array = new int[size];
			for (int i = 0; i < size; i++)
				array[i] = readInt();
			return array;
		}

		public long[] readLongArray(int size) {
			long[] array = new long[size];
			for (int i = 0; i < size; i++)
				array[i] = readLong();
			return array;
		}

		public double[] readDoubleArray(int size) {
			double[] array = new double[size];
			for (int i = 0; i < size; i++)
				array[i] = readDouble();
			return array;
		}

		public String[] readStringArray(int size) {
			String[] array = new String[size];
			for (int i = 0; i < size; i++)
				array[i] = readString();
			return array;
		}

		public char[][] readTable(int rowCount, int columnCount) {
			char[][] table = new char[rowCount][columnCount];
			for (int i = 0; i < rowCount; i++) {
				for (int j = 0; j < columnCount; j++)
					table[i][j] = readCharacter();
			}
			return table;
		}

		public void readIntArrays(int[]... arrays) {
			for (int i = 0; i < arrays[0].length; i++) {
				for (int j = 0; j < arrays.length; j++)
					arrays[j][i] = readInt();
			}
		}
	}
}
